package orm

import (
	"context"
	"database/sql"
	"orm/internal/errs"
	"strings"
)

type Deleter[T any] struct {
	tablename string
	sb        *strings.Builder
	model     *model
	where     []Predicate
	args      []any
}

func (d *Deleter[T]) Build() (*Query, error) {
	d.sb = &strings.Builder{}
	var err error
	d.model, err = parseModel(new(T))
	if err != nil {
		return nil, err
	}
	d.sb.WriteString("DELETE FROM ")
	if d.tablename != "" {
		d.sb.WriteString(d.tablename)
	} else {
		d.sb.WriteByte('`')
		d.sb.WriteString(d.model.tableName)
		d.sb.WriteByte('`')
	}

	if len(d.where) > 0 {
		d.sb.WriteString(" WHERE ")
		p := d.where[0]
		for i := 1; i < len(d.where); i++ {
			p = p.And(d.where[i])
		}
		if err := d.buildExpression(p); err != nil {
			return nil, err
		}
	}
	d.sb.WriteByte(';')
	return &Query{
		SQL:  d.sb.String(),
		Args: d.args,
	}, nil
}
func (d *Deleter[T]) buildExpression(expr Expression) error {
	switch exp := expr.(type) {
	case nil:
	case Predicate:
		if err := d.buildExpression(exp.left); err != nil {
			return err
		}
		d.sb.WriteString(exp.op.String())
		if err := d.buildExpression(exp.right); err != nil {
			return err
		}
	case value:
		d.sb.WriteByte('?')
		d.sb.WriteByte(')')
		d.addArgs(exp.val)
	case Column:
		// 字段不对，或者说列不对
		fd, ok := d.model.fields[exp.name]
		if !ok {
			return errs.NewErrUnknownField(exp.name)
		}
		d.sb.WriteByte('(')
		d.sb.WriteByte('`')
		d.sb.WriteString(fd.colName)
		d.sb.WriteByte('`')
	default:
		return errs.NewErrUnsupportedExpression(expr)
	}
	return nil
}

func (d *Deleter[T]) addArgs(arg any) {
	if d.args == nil {
		d.args = make([]any, 0, 4)
	}
	d.args = append(d.args, arg)

}

func (d *Deleter[T]) From(table string) *Deleter[T] {
	d.tablename = table
	return d
}

func (d *Deleter[T]) Where(predicate ...Predicate) *Deleter[T] {
	d.where = predicate
	return d
}

func (d *Deleter[T]) Exec(ctx context.Context) (sql.Result, error) {
	//TODO implement me
	panic("implement me")
}
